package com.fitso.model.bean.nutrition;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;

import com.fitso.model.bean.measure.energy.Calorie;
import com.fitso.model.bean.measure.mass.Gram;
import com.fitso.model.bean.measure.mass.Mass;

/**
 * <p>
 * Organic compound that can store and transport energy or a structural
 * component of cells.
 * </p>
 * 
 * @author timothy storm
 * @see <a href="http://en.wikipedia.org/wiki/Carbohydrate">Carbohydrate</a>
 */
public class Carbohydrates extends Nutrient implements Serializable {
	// Only change on breaking changes, i.e., removing fields
	private static final long serialVersionUID = 1L;
	
	private Mass _sugar, _fiber;

	public Carbohydrates() {
		super();
	}

	public Carbohydrates(Mass totalMass) {
		super(totalMass);
	}

	public boolean equals(Object o) {
		if (o == null) {
			return false;
		}
		if (o == this) {
			return true;
		}
		if (o.getClass() != getClass()) {
			return false;
		}

		Carbohydrates other = (Carbohydrates) o;
		return new EqualsBuilder().appendSuper(super.equals(other)).append(_fiber, other._fiber).append(_sugar,
				other._sugar).isEquals();
	}

	protected Calorie getCaloriesPerGram() {
		return new Calorie(4.0);
	}

	/**
	 * Complex is always calculated by subtracting the mass of fiber and sugar
	 * from the total mass
	 * 
	 * @return calculated complex carbohydrates
	 */
	public Mass getComplex() {
		Gram complex = new Gram(getMass());
		complex.subtract(getSugar());
		complex.subtract(getFiber());
		return complex;
	}

	public Mass getFiber() {
		return _fiber;
	}

	public Mass getSugar() {
		return _sugar;
	}

	/**
	 * Equivalent to {@link #getMass()} but is available for clarity
	 * 
	 * @return
	 */
	public Mass getTotal() {
		return super.getMass();
	}

	public int hashCode() {
		return new HashCodeBuilder().appendSuper(super.hashCode()).append(_fiber).append(_sugar).toHashCode();
	}

	public void setFiber(Mass fiberMass) {
		_fiber = fiberMass;
	}

	public void setSugar(Mass sugarMass) {
		_sugar = sugarMass;
	}

	/**
	 * Equivalent to {@link #setMass(Mass)} but is available for clarity
	 * 
	 * @return
	 */
	public void setTotal(Mass mass) {
		super.setMass(mass);
	}

	public String toString() {
		return new ReflectionToStringBuilder(this).toString();
	}

	public Mass[] getAllCarbs() {
		List<Mass> carbs = new ArrayList<Mass>();
		carbs.add(getTotal());
		carbs.add(_sugar);
		carbs.add(_fiber);
		return carbs.toArray(new Mass[carbs.size()]);
	}
}
